15-2 蝳?

函式(Functions)也是 M 檔案的一種,它可以接受輸入變數,並將運算結果送至輸出變數,運算過程所產生的變數都存放在函式本身的工作空間,並不會和 MATLAB 基本工作空間的變數相互覆蓋。因此,函式特別適用於大型程式碼,他會使您的程式碼模組化(Modularized)並易於維護與改進。

舉例來說,func1.m 就是筆者所撰寫的一個小函式,它的功能是算出一向量的平均值,我們可用 type 指令顯示其內容:

>> type func1.m function average = func1(vector) average = sum(vector)/length(vector); % 計算平均值

此函式的第一列為「函式定義列」(Function Definition Line),定義了此函式的名稱(即func1,最好和檔案的主檔名相同)、輸入引數(即 vector)、輸出引數(即 average),而 function 則為關鍵字,代表此 M 檔案為一函式。第二列則為函式主體(Function Body),規範函式的運算過程,並指定輸出引數的值。欲呼叫此函式,可輸入如下:

>> vec = [1 5 3]; >> ave = func1(vec) ave = 3

欲加上函式的「線上輔助說明」(On-line Help),可在函式定義列下直接加入註解,例如在函式 func2.m,我們已加上了線上輔助說明::

>> type func2.m function average = func(vector) % FUNC2 A simple function with a single help line. % % Usage of this function: % output = func2(input) % "output" is the average of the input vector "input". % Roger Jang, 19991123. average = sum(vector)/length(vector); % 計算平均值

在函式定義列之後的連續註解(以「%」開頭),即為函式的線上輔助說明,若在 MATLAB 輸入「help 函式主檔名」,即可看到這些輔助說明,例如:

>> help func2 FUNC2 A simple function with a single help line. Usage of this function: output = func2(input) "output" is the average of the input vector "input".

因此,您可以將所有有關此函式的說明,包含用法、演算法、參考資料、最後修改日期、作者等資訊,全部寫入線上輔助說明,以利使用者(可能就是您自己)查看。

Hint
在上例中,「Roger Jang, 19991023」並未呈現在func2的函式的線上輔助說明,這使因為此列和前面的註解已分離,並不屬於「連續」的註解。

在一函式的線上輔助說明裡,最重要的就是第一列,這一列又稱為「H1 輔助說明」(H1 Help),當您使用「lookfor keyword」去查詢 MATLAB 指令時,MATLAB 事實上就是以所給的關鍵字和搜尋路徑上所有的 MATLAB 函式的「H1 輔助說明」進行一一比對,以找出相關的指令。例如:

>> lookfor 'help line' FUNC2 A simple function with a single help line.

Hint
當您安裝了很多工具箱,或是您的搜尋路徑很長時,lookfor指令的執行時間就可能會較長。

若您有很多和某應用相關的函式,您可以將這些函式存放於一子目錄內,並將此目錄加入搜尋路徑,使 MATLAB 在任何目錄內,均可執行此目錄內的函式。 欲加入路徑,可用 addpath 指令,欲移除路徑,可用rmpath指令,在此不在贅述。此外,您也可以建立一目錄的線上輔助說明,只需在此目錄下加入一特定檔案「 Contents.m」,此檔案只能包含輔助說明文字,同時每列均需以「%」開頭,MATLAB 會在您輸入「help 目錄名稱」時,顯示在「目錄名稱」下的 Contents.m 的輔助說明。

MATLAB 的函式名稱和變數名稱都有相同的限制:只接受前 31 個字母(MATLAB 5.x)或前 63 個字母(MATLAB 6.x 和 7.x),而且必需以英文字母作為開頭。此外,當檔案名稱和函式名稱不同時,我們仍可依檔案名稱呼叫檔案,函式名稱將被忽略。(在 MATLAB 6.x 和 7.x,你可以使用 namelengthmax 指令來查到變數名稱的最大長度。)

一個函式可以有多輸入及輸出,例如:func3.m 可接受兩個輸入並產生兩個輸出,這兩個輸出分別是兩個輸入向量的平均值,其程式碼可顯示如下:

>> type func3.m function [ave1, ave2] = func3(vector1, vector2); ave1 = sum(vector1)/length(vector1); ave2 = sum(vector2)/length(vector2);

func3.m 的典型呼叫方式如下:

>> [a, b] = func3([1 2 3], [4 5 6 7 8]) a = 2 b = 6

此外,在一函式中,我們可用內建變數 nargin 及 nargout 來決定此函式的實際輸入和輸出變數的個數,其主要功能為:

Hint
  • nargin: Number of Arguments of Inputs
  • nargout: Number of Arguments of outputs

例如:上述函式 func3.m 可改寫成 func4.m,其內容如下:

>> type func4.m function [ave1, ave2] = func4(vector1, vector2) if nargin == 1, % 只有一個輸入變數 ave1 = sum(vector1)/length(vector1); end if nargout == 2, % 有兩個輸出變數 ave1 = sum(vector1)/length(vector1); ave2 = sum(vector2)/length(vector2); end

此時 func4.m 就可以接受一個或兩個輸入變數:

>> [a, b] = func4([1 2 3], [4 5 6 7 8]) a = 2 b = 6 >> c = func4([1 3 5 7 9]) c = 5

MATLAB 的函式亦可傳送不定數目的輸入引數和輸出引數,但由於實際應用機會不多,故在此不再贅述,有興趣的讀者,可參考 varargin 和 varargout 的線上輔助說明。

Hint
從外表上來看,MATLAB 函式的變數傳遞方法是所謂的“Call by Value”,亦即在函式的工作空間中,所有的輸入變數均是父工作空間(Parent Workspace)的一份拷貝本,因此在函式中更改這些輸入變數,並不會影響原先父工作空間的變數。在實際運作上,若輸入變數未被修改,則MATLAB 採用“Call by Reference”,否則,則採用“Call by Value”。

若要在函式內知道此函式的檔案名稱,可用 mfilename 指令;若要在函式內知道此函式的輸入變數名稱,可用 inputname 指令,有興趣的讀者,可由 help mfilename 或 help inputname 得到更詳細的資訊。


MATLAB程式設計:入門篇